//============================================================================
// Name        : graphics.cpp
// Author      : dfoelber
//============================================================================

#include "graphics/graphics.h"
#include "draw/SDL_draw.h"
#include "image_manager.h"
#include "util.h"
#include <iostream>

using namespace std;

Graphics* Graphics::instance = NULL;

/**
* Private constructor
**/
Graphics::Graphics()
{
}

/**
* Deconstructor
**/
Graphics::~Graphics()
{
	for(int i = 0; i < (int)fonts.size(); i++)
		for(int j = 0; j < (int)fonts[i].size(); j++)
			TTF_CloseFont( fonts[i][j] );
}

void Graphics::Load()
{
	string directory;
	if( LINUX_FILESYSTEM )
		directory += "/usr/share/xyne/";
	string filename;
	
	vector<TTF_Font*> knight;
	filename = directory + "knight.ttf";
	knight.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_XSMALL ));
	knight.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_SMALL ));
	knight.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_MEDIUM ));
	knight.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_NORMAL ));
	knight.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_LARGE ));
	fonts.push_back(knight);
	
	vector<TTF_Font*> cicle;
	filename = directory + "cicle_fina.ttf";
	cicle.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_XSMALL ));
	cicle.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_SMALL ));
	cicle.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_MEDIUM ));
	cicle.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_NORMAL ));
	cicle.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_LARGE ));
	fonts.push_back(cicle);
	
	vector<TTF_Font*> deja;
	filename = directory + "DejaVuSans.ttf";
	deja.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_XSMALL ));
	deja.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_SMALL ));
	deja.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_MEDIUM ));
	deja.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_NORMAL ));
	deja.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_LARGE ));
	fonts.push_back(deja);
	
	vector<TTF_Font*> dejab;
	filename = directory + "DejaVuSans-Bold.ttf";
	dejab.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_XSMALL ));
	dejab.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_SMALL ));
	dejab.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_MEDIUM ));
	dejab.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_NORMAL ));
	dejab.push_back(TTF_OpenFont( filename.c_str(), FONT_SIZE_LARGE ));
	fonts.push_back(dejab);
}

/**
* Singleton accessor
* 
* @return Singleton instance
**/
Graphics* Graphics::GetGraphics()
{
	if( instance == NULL )
	{
		instance = new Graphics();
	}
	
	return instance;
}

void Graphics::CreateStandardTooltip( string tooltip, Surface** surface, Surface** background, int width )
{
	FontSize fontSize = FONT_SIZE_MEDIUM;
	int textWidth = 0, textHeight = 0, strWidth = 0, strHeight = 0;
	vector<string> lines = Util::Format(tooltip, FONT_DEJA_VU_SANS, fontSize, width, &textWidth, &textHeight);
	
	textHeight += TOOLTIP_RADIUS * 2;
	
	// Create the tooltip's foreground
	*surface = ImageManager::GetManager()->CreateImage(textWidth + TOOLTIP_RADIUS * 2, textHeight);
	int x = TOOLTIP_RADIUS; int y = TOOLTIP_RADIUS;
	
	// Draw the text
	for( int i = 0; i < (int)lines.size(); i++ )
	{
		if( lines[i].empty() ) lines[i] = " ";
		DrawFont( *surface, lines[i], FONT_DEJA_VU_SANS, fontSize, COLOR_BLACK, x, y );
		TTF_SizeText(GetFont(FONT_DEJA_VU_SANS,fontSize), lines[i].c_str(), &strWidth, &strHeight);
		y += strHeight + 1;
	}
	
	// Create the tooltip's background
	*background = ImageManager::GetManager()->CreateImage(textWidth + TOOLTIP_RADIUS * 2, textHeight);
	Draw_FillRound( (*background)->GetSurface(), 0, 0, textWidth + TOOLTIP_RADIUS * 2, textHeight, 5, COLOR_WHITE.ToUint32() );
	SDL_SetAlpha( (*background)->GetSurface(), SDL_SRCALPHA, 200 );
}

void Graphics::DrawFont( Surface* surface, string s, Font font, FontSize size, Color c, int x, int y, int alpha )
{
	TTF_Font* f = GetFont(font, size);
	
	if (f != NULL)
	{
		SDL_Color color = {c.r,c.g,c.b};
		SDL_Surface* fontSurface = TTF_RenderText_Solid( f, s.c_str(), color );
		
		SDL_SetAlpha( fontSurface, SDL_SRCALPHA, alpha );
		
		Surface* temp = new Surface( fontSurface );
		temp->Apply( surface, x, y );
		
		delete temp;
	}
}

void Graphics::DrawFont( Surface* surface, string s, Font font, FontSize size, Color c, int x, int y, int width, int height, int alignment, int alpha )
{
	TTF_Font* f = GetFont(font, size);
	
	int textWidth = 0, textHeight = 0;
	
	if (f != NULL && TTF_SizeText(f, s.c_str(), &textWidth, &textHeight) == 0)
	{
		if ((int)(alignment & ALIGNMENT_MIDDLE) > 0)
		{
			x += (width / 2) - (textWidth / 2);
		}
		else if ((int)(alignment & ALIGNMENT_RIGHT) > 0)
		{
			x += width - textWidth;
		}
		if ((int)(alignment & ALIGNMENT_CENTER) > 0)
		{
			y += (height / 2) - (textHeight / 2);
		}
		else if ((int)(alignment & ALIGNMENT_BOTTOM) > 0)
		{
			y += height - textHeight;
		}
		
		SDL_Color color = {c.r,c.g,c.b};
		SDL_Surface* fontSurface = TTF_RenderText_Solid( f, s.c_str(), color );
		
		SDL_SetAlpha( fontSurface, SDL_SRCALPHA, alpha );
		
		Surface* temp = new Surface( fontSurface );
		temp->Apply( surface, x, y );
		
		delete temp;
	}
}

void Graphics::GetFontSize( Font font, string s, FontSize size, int* w, int* h )
{
	TTF_Font* f = GetFont( font, size );
	
	if (f)
		TTF_SizeText(f, s.c_str(), w, h );
}
	
TTF_Font* Graphics::GetFont( Font font, FontSize size )
{
	vector<TTF_Font*> f = fonts[font];
	
	switch( size )
	{
	case FONT_SIZE_XSMALL: return f[0];
	case FONT_SIZE_SMALL: return f[1];
	case FONT_SIZE_MEDIUM: return f[2];
	case FONT_SIZE_NORMAL: return f[3];
	case FONT_SIZE_LARGE: return f[4];
	}
	
	return f[3];
}
